import Data from "@/lib/core/data/getdata.js"
import API from "@/lib/http/api.js"
import attrsCheck from "@/lib/general/attrsCheck.js"
import vNode from "../structs/render_vNode"
import async from "@/lib/general/async.js"

function c() {
    this.context = undefined
    this.layout = undefined
    this.nodes = undefined
    this.childSource= []
}

c.prototype = new async()
c.prototype.constructor = c

/**make
 * get an config to make virtual nodes.
 * config see more: HELP_COMPILE_CONFIG_FILE.md
 * @param {*} cfgURI config file uri.
 * @param {*} context vue context.
 */
c.prototype.make = function (cfgURI, context = undefined) {
    this.context = context
    let self = this
    cfgURI += cfgURI.indexOf('?') > -1 ? "&timestamp=" : "?timestamp=" + Date.parse(new Date()).toString()
    API.getContext(cfgURI).then((response) => {
        (new attrsCheck(response.data, ['dataSet', 'layout'])).then((data) => {
            self.layout = data.layout
            Data.create(data.dataSet).asyncThen((data) => {
                this.nodes = this.initInstance(data)
                this.target = this
                this.status = true
            }, (error) => {
                throw error
            })
        }).catch((error) => {
            throw error
        })
    }).catch((error) => {
        throw error
    })
    return this
}

c.prototype.initInstance = function (data) {
    for (let o in data) {
        this.context[o] = data[o]
    }
    return this.createVnode(this.layout.nodes)
}

c.prototype.createVnode = function (cfg) {
    let v_node = undefined
    if (typeof (cfg) == "string") {
        cfg = JSON.parse(cfg)
    }
    switch (typeof (cfg)) {
        case "object": {
            if (Array.isArray(cfg)) {
                cfg.forEach(o => {
                    v_node = new vNode(o.el, o.attributes)
                    if ('childs' in o) {
                        for (let child in o.childs) {
                            if (typeof (o.childs[child]) != 'string') {
                                v_node.appendChildNode(this.createVnode(o.childs[child]))
                            }
                            else {
                                v_node.setValue(o.childs[child])
                            }
                        }
                    }
                    if ('text' in o) {
                        v_node.setValue(o.text)
                    }
                    if ('data' in o) {
                        v_node.setDataSource(o.data)
                    }
                })
                return v_node
            }
            else {
                v_node = new vNode(cfg.el, cfg.attributes)
                if ('childs' in cfg) {
                    for (let child in cfg.childs) {
                        if (typeof (cfg.childs[child]) != 'string') {
                            v_node.appendChildNode(this.createVnode(cfg.childs[child]))
                        }
                        else {
                            v_node.setValue(cfg.childs[child])
                        }
                    }
                }
                if ('text' in cfg) {
                    v_node.setValue(cfg.text)
                }
                if ('data' in cfg) {
                    v_node.setDataSource(cfg.data)
                }
                return v_node
            }
        }
    }
}

const compile = new c()

export default compile